home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -seriously_amiga- / shareware / programming / c / amivogl-mdev / drivers / amiga.c next >
C/C++ Source or Header  |  1998-01-12  |  38KB  |  1,305 lines

  1. /*
  2.  * Vogle driver for the Amiga
  3.  *
  4.  * Written By: Dr. Charles E. Campbell, Jr.
  5.  * Version   : 1.00
  6.  * Date      : September 28, 1993
  7.  *
  8.  */
  9. #include <stdio.h>
  10. #include <fcntl.h>
  11. #include <errno.h>
  12. #include <stdlib.h>
  13. #include <ctype.h>
  14.  
  15. #include <functions.h>
  16. #include <exec/types.h>
  17. #include <intuition/intuition.h>
  18. #include <libraries/dos.h>
  19. #include <graphics/rastport.h>
  20. #include <graphics/gfxmacros.h>
  21. #include <graphics/text.h>
  22. #include <exec/memory.h>
  23. #include <devices/inputevent.h>
  24. #include <clib/exec_protos.h>
  25. #include <clib/intuition_protos.h>
  26. #include <clib/console_protos.h>
  27.  
  28. #include "vogl.h"
  29.  
  30. #define INTUITION_REV    ((unsigned long) 33L)
  31. #define GRAPICS_REV        ((unsigned long) 33L)
  32.  
  33. /* --------------------------------------------------------------------------
  34.  * Definitions Section:
  35.  */
  36. #define SNGLBUFMODE    0    /* default scrbufmode value                    */
  37. #define DBLBUFMODE    1    /* scrbufmode value                            */
  38. #define RAWKEYBUF    128    /* initial size of rawkey buffer conversion    */
  39. #define KEYBUF        256    /* max size of keybuffer to be read            */
  40.  
  41. #define FONTSEP        ';'
  42. #define MAXVRTX        200
  43. #define MAXSTRING    1024
  44.  
  45. #ifdef SASC
  46. #define USESVMODE
  47. #endif
  48.  
  49. #ifdef AZTEC_C
  50. # define MEMTYPE    (MEMF_CHIP|MEMF_CLEAR)
  51. #else
  52. # define MEMTYPE    (MEMF_CLEAR)
  53. #endif
  54.  
  55. /* head_link: handles the generation of head-linked lists.  Note that 
  56.  *   each structure is assumed to have the member "nxt".
  57.  *   The new member becomes "head" - ie. oldest is last in the linked list,
  58.  *   the newest is first.
  59.  */
  60. #define head_link(structure,head,fail_msg) {         \
  61.     structure *newstr;                               \
  62.     newstr= (structure *) malloc(sizeof(structure)); \
  63.     if(!newstr) printf("***out of memory*** <%s>\n",fail_msg);   \
  64.     newstr->nxt= head;                               \
  65.     head    = newstr;                                \
  66.     }
  67.  
  68. /* stralloc: allocates new memory for and copies a string into the new mem */
  69. #define stralloc(ptr,string,fail_msg) {                             \
  70.     ptr= (char *) calloc((size_t) strlen(string) + 1,sizeof(char)); \
  71.     if(!ptr) printf("***out of memory*** <%s>\n",fail_msg);                  \
  72.     strcpy(ptr,string);                                             \
  73.     }
  74.  
  75. /* --------------------------------------------------------------------------
  76.  * Typedefs:
  77.  */
  78. typedef struct FontList_str FontList;
  79.  
  80. /* --------------------------------------------------------------------------
  81.  * Data Structures:
  82.  */
  83. struct FontList_str {
  84.     char            *fontspec;
  85.     struct TextFont *textfont;
  86.     FontList        *nxt;
  87.     };
  88.  
  89. /* --------------------------------------------------------------------------
  90.  * Extern Data:
  91.  */
  92. #ifdef AZTEC_C
  93. extern int Enable_Abort;
  94. #else
  95. void __regargs __checkabort (void);
  96. #endif
  97.  
  98. /* --------------------------------------------------------------------------
  99.  * Local Data:
  100.  */
  101. WORD                 *voglareaBuffer= NULL;
  102. struct BitMap        *voglback      = NULL;
  103. struct BitMap        *voglfront     = NULL;
  104. struct DiskFontBase  *DiskfontBase  = NULL;
  105. struct GfxBase       *GfxBase       = NULL;
  106. struct IntuiText     *voglitext     = NULL;
  107. struct IntuitionBase *IntuitionBase = NULL;
  108. struct IOStdReq      *vogl_cd_ioreq = NULL;
  109. struct Library       *ConsoleDevice = NULL;
  110. struct RastPort      *voglrastport  = NULL;
  111. struct Screen        *voglscreen    = NULL;
  112. struct TextAttr      *vogltextattr  = NULL;
  113. struct TmpRas        *vogltmpras    = NULL;
  114. struct Window        *voglwindow    = NULL;
  115.  
  116. static char               useborder       = 0;
  117. static char               scrbufmode      = SNGLBUFMODE;
  118. static char              *rawkeybuf       = NULL;
  119. static int                grfxmode        = 0;
  120. static int                currcolor       = 0;
  121. static UBYTE             *voglstring      = NULL;
  122. static UWORD              scrdepth        = 4;
  123. static UWORD              scrwidth        = 0;
  124. static UWORD              scrheight       = 0;
  125. static UWORD              voglscrbordleft = 0;
  126. static UWORD              voglscrbordright= 0;
  127. static UWORD              voglscrbordtop  = 0;
  128. static UWORD              voglscrbordbttm = 0;
  129. static USHORT             screenviewmode  = HIRES|LACE;
  130. static LONG               qtyrawkeybuf    = 0L;
  131. static FontList          *fontlisthd      = NULL;
  132. static struct InputEvent *voglievent      = NULL;
  133. static PLANEPTR          voglplaneptr     = NULL;
  134.  
  135. /* voglkeybuf
  136.  *   |uuuddddddduuuuu|    u=unused  d=data
  137.  *      ^       ^
  138.  *   ikeybgn    ikeyend   (always point to unused)
  139.  */
  140. static char     voglkeybuf[KEYBUF];
  141. static unsigned ikeyend= 0;            /* points just-past chars in voglkeybuf        */
  142. static unsigned ikeybgn= KEYBUF-1;    /* points just-before chars in voglkeybuf    */
  143.  
  144.  
  145. /* --------------------------------------------------------------------------
  146.  * Local Prototypes:
  147.  */
  148. void AMIGA_config(char *);                             /* amiga.c         */
  149. int AMIGA_init(void);                                  /* amiga.c         */
  150. static struct BitMap *makeBitMap(void);                /* amiga.c         */
  151. void freeBitMap(struct BitMap *);                      /* amiga.c         */
  152. int AMIGA_exit(void);                                  /* amiga.c         */
  153. void AMIGA_draw( int, int);                            /* amiga.c         */
  154. int AMIGA_getkey(void);                                /* amiga.c         */
  155. int AMIGA_checkkey(void);                              /* amiga.c         */
  156. int AMIGA_locator( int *, int *);                      /* amiga.c         */
  157. void AMIGA_clear(void);                                /* amiga.c         */
  158. void AMIGA_color(int);                                 /* amiga.c         */
  159. void AMIGA_mapcolor( int, int, int, int);              /* amiga.c         */
  160. int AMIGA_font(char *);                                /* amiga.c         */
  161. void AMIGA_char(char);                                 /* amiga.c         */
  162. void AMIGA_string(char *);                             /* amiga.c         */
  163. void AMIGA_fill( int, int[], int[]);                   /* amiga.c         */
  164. int AMIGA_backbuffer(void);                            /* amiga.c         */
  165. int AMIGA_swapbuffer(void);                            /* amiga.c         */
  166. void AMIGA_frontbuffer(void);                          /* amiga.c         */
  167. void _AMIGA_devcpy(void);                              /* amiga.c         */
  168.  
  169.  
  170. /* --------------------------------------------------------------------------
  171.  * Device Entry
  172.  *    fontname;height[;{BEIPU}]
  173.  *   B == bold
  174.  *   E == extended
  175.  *   I == italic
  176.  *   P == plain (default)
  177.  *   U == underlined
  178.  */
  179. static DevEntry amigadev = {
  180.     "AMIGA",            /* name of device                                */
  181.     "topaz;9;P",        /* name of small "hardware" font                */
  182.     "topaz;11;P",        /* name of large "hardware" font                */
  183.     AMIGA_backbuffer,    /* initializes double buffering                    */
  184.     AMIGA_char,            /* prints a "hardware" character                */
  185.     AMIGA_checkkey,        /* check if keyboard key hit, return it            */
  186.     AMIGA_clear,        /* clears viewport to background                */
  187.     AMIGA_color,        /* change current color index                    */
  188.     AMIGA_draw,            /* draws line from current to (x,y)                */
  189.     AMIGA_exit,            /* cleans up and allows vogle to exit            */
  190.     AMIGA_fill,            /* does filled polygons                            */
  191.     AMIGA_font,            /* sets up a hardware font                        */
  192.     AMIGA_frontbuffer,    /* switches drawing into front buffer            */
  193.     AMIGA_getkey,        /* gets a char of input                            */
  194.     AMIGA_init,            /* enables graphics                                */
  195.     AMIGA_locator,        /* finds mouse position in vogle device coords    */
  196.     AMIGA_mapcolor,        /* changes color at index to given rgb value    */
  197.     AMIGA_string,        /* prints a string of hardware text                */
  198.     AMIGA_swapbuffer};    /* swaps front and back buffers                    */
  199.  
  200. /* ==========================================================================
  201.  * Source Code:
  202.  */
  203.  
  204. /* AMIGA_config: This function modifies what AMIGA_init does.  It allows the
  205.  * user to control the type of screen and bitmaps used.  Note that one may
  206.  * use extra half-brite mode, too.  I put in ham mode since I expect to
  207.  * attempt to do some shading someday.
  208.  *
  209.  * The AMIGA_init sets up a gimmezerozero window using a custom Screen and
  210.  * BitMap.
  211.  *
  212.  * The config string may include:
  213.  *      b : use border&title on window
  214.  *        d : double buffer mode
  215.  *        e : extra halfbrite mode
  216.  *        h : ham graphics mode
  217.  *      s : single buffer mode
  218.  *        1-5 : 1,2,3, 4, 5 bit planes (2,4,8,16,64 colors, respectively)
  219.  *
  220.  * Screen height will be max and interlaced.
  221.  * Screen width  will be 640 for 1-4 bit planes and 320 otherwise
  222.  */
  223. void AMIGA_config(char *config)
  224. {
  225. Enable_Abort=0;
  226.  
  227. for(; *config; ++config) switch(*config) {
  228.  
  229. case 'b':    /* use border on window */
  230.     useborder= 1;
  231.     break;
  232.  
  233. case 'd':    /* double buffer mode    */
  234.     scrbufmode= DBLBUFMODE;
  235.     break;
  236.  
  237. case 'e':    /* extra halfbrite mode    */
  238.     screenviewmode= LACE|EXTRA_HALFBRITE;
  239.     scrdepth     = 6;
  240.     break;
  241.  
  242. case 'h':    /* ham mode                */
  243.     screenviewmode= LACE|HAM;
  244.     scrdepth     = 6;
  245.     break;
  246.  
  247. case 's':    /* single buffer mode */
  248.     scrbufmode= SNGLBUFMODE;
  249.     break;
  250.  
  251. case '1':    /* one bit plane        */
  252.     screenviewmode= LACE|HIRES;
  253.     scrdepth     = 1;
  254.     break;
  255.  
  256. case '2':    /* two bit planes        */
  257.     screenviewmode= LACE|HIRES;
  258.     scrdepth     = 2;
  259.     break;
  260.  
  261. case '3':    /* three bit planes        */
  262.     screenviewmode= LACE|HIRES;
  263.     scrdepth     = 3;
  264.     break;
  265.  
  266. case '4':    /* four bit planes        */
  267.     screenviewmode= LACE|HIRES;
  268.     scrdepth     = 4;
  269.     break;
  270.  
  271. case '5':
  272.     screenviewmode= LACE;
  273.     scrdepth     = 5;
  274.     break;
  275.  
  276. default:
  277.     screenviewmode= LACE|HIRES;
  278.     scrdepth     = 4;
  279.     printf("***warning*** AMIGA_config: bad config<%s> string\n",config);
  280.     break;
  281.     }
  282. }
  283.  
  284. /* -------------------------------------------------------------------------- */
  285.  
  286. /* AMIGA_init: initialises drawing canvas to occupy current window
  287.  *  a routine which enables graphics on the device, sets the default
  288.  *  colour map, and sets vdevice.maxS{x,y} and vdevice.minS{x,y} to the
  289.  *  window size in pixels.
  290.  */
  291. int AMIGA_init(void)
  292. {
  293. int               gx,gy;            /* getprefposandsize x,y    */
  294. int               gxs,gys;            /* getprefposandsize xs,ys    */
  295. struct Screen    *wbscreen=NULL;
  296. struct NewScreen *newscreen=NULL;
  297. struct NewWindow *newwindow=NULL;
  298.  
  299. Enable_Abort=0;
  300.  
  301. /* don't let user initialize twice (or more!) */
  302. if(IntuitionBase) {
  303.     printf("***warning*** AMIGA_init: attempt to initialize twice!\n");
  304.     return 0;
  305.     }
  306.  
  307. /* allocate some memory needed for the ConsoleDevice */
  308. vogl_cd_ioreq= (struct IOStdReq *)
  309.   AllocMem(sizeof(struct IOStdReq),MEMTYPE);
  310. if(!vogl_cd_ioreq) {
  311.     AMIGA_exit();
  312.     printf("***warning*** unable to allocate a IOStdReq\n");
  313.     goto initproblem;
  314.     }
  315.  
  316. /* open Intuition */
  317. IntuitionBase= (struct IntuitionBase *)
  318.   OpenLibrary((UBYTE *) "intuition.library",INTUITION_REV);
  319. if(IntuitionBase == NULL) {
  320.     AMIGA_exit();
  321.     printf("***warning*** unable to open Intuition Library\n");
  322.     goto initproblem;
  323.     }
  324.  
  325. /* open Graphics */
  326. GfxBase= (struct GfxBase *)
  327.   OpenLibrary((UBYTE *) "graphics.library",INTUITION_REV);
  328. if(GfxBase == NULL) {
  329.     AMIGA_exit();
  330.     printf("***warning*** unable to open Graphics Library\n");
  331.     goto initproblem;
  332.     }
  333.  
  334. /* open DiskFont */
  335. DiskfontBase= (struct DiskFontBase *)
  336.   OpenLibrary((UBYTE *) "diskfont.library",0L);
  337. if(DiskfontBase == NULL) {
  338.     AMIGA_exit();
  339.     printf("***warning*** unable to open DiskFont library\n");
  340.     goto initproblem;
  341.     }
  342.  
  343. /* open ConsoleDevice */
  344. if(OpenDevice((UBYTE *) "console.device",-1L,(struct IORequest *) vogl_cd_ioreq,0L) != 0) {
  345.     AMIGA_exit();
  346.     printf("***warning*** unable to open DiskFont library\n");
  347.     goto initproblem;
  348.     }
  349. ConsoleDevice= (struct Library *) vogl_cd_ioreq->io_Device;
  350.  
  351. /* determine screen width and height from screenviewmode */
  352.  
  353. #ifdef USESVMODE
  354.  
  355. /* this code uses screenviewmode by itself, setting up standard
  356.  * height and width
  357.  */
  358. scrwidth= 640;
  359. if( (screenviewmode & HAM)   ||
  360.    !(screenviewmode & HIRES) ||
  361.     (screenviewmode & EXTRA_HALFBRITE)) scrwidth= 320;
  362. scrheight= 200;
  363. if(screenviewmode & LACE) scrheight= 400;
  364.  
  365. #else
  366.  
  367. /* lock WorkBench screen and query it for its dimensions */
  368. wbscreen= LockPubScreen((UBYTE *) "Workbench");
  369. if(wbscreen) {
  370.     scrheight= wbscreen->Height;
  371.     scrwidth = wbscreen->Width;
  372.  
  373.     
  374.     if     ( (wbscreen->ViewPort.Modes & LACE)  && !(screenviewmode & LACE))  scrheight/= 2;
  375.     else if(!(wbscreen->ViewPort.Modes & LACE)  &&  (screenviewmode & LACE))  scrheight*= 2;
  376.     if     ( (wbscreen->ViewPort.Modes & HIRES) && !(screenviewmode & HIRES)) scrwidth /= 2;
  377.     else if(!(wbscreen->ViewPort.Modes & HIRES) &&  (screenviewmode & HIRES)) scrwidth *= 2;
  378.  
  379.     voglscrbordtop  = wbscreen->WBorTop + wbscreen->Font->ta_YSize + 1;
  380.     UnlockPubScreen(NULL,wbscreen);
  381.     }
  382. else voglscrbordtop= 0;
  383. #endif
  384.  
  385. /* allocate a NewScreen in CHIP memory */
  386. newscreen= AllocMem(sizeof(struct NewScreen),MEMTYPE);
  387. if(!newscreen) {
  388.     AMIGA_exit();
  389.     printf("***warning*** unable to allocate a NewScreen\n");
  390.     goto initproblem;
  391.     }
  392.  
  393. /* set up both front and back BitMaps.  Note that Vogl signals
  394.  * use of double buffering after this function is called
  395.  * (the doublebuffer() function calls AMIGA_backbuffer
  396.  * which begins backbuffering)
  397.  */
  398. voglfront= makeBitMap();
  399. if(!voglfront) {
  400.     AMIGA_exit();
  401.     printf("***warning*** unable to allocate front BitMap\n");
  402.     goto initproblem;
  403.     }
  404.  
  405. voglback= makeBitMap();
  406. if(!voglback) {
  407.     AMIGA_exit();
  408.     printf("***warning*** unable to allocate back BitMap\n");
  409.     goto initproblem;
  410.     }
  411.  
  412. /* initialize NewScreen */
  413. newscreen->LeftEdge    = 0;
  414. newscreen->TopEdge     = 0;
  415. newscreen->Width       = scrwidth;
  416. newscreen->Height      = scrheight;
  417. newscreen->Depth       = scrdepth;
  418. newscreen->DetailPen   = 1;
  419. newscreen->BlockPen    = 0;
  420. newscreen->ViewModes   = screenviewmode;
  421. newscreen->Type        = CUSTOMSCREEN|CUSTOMBITMAP|SCREENQUIET;
  422. newscreen->Font        = (struct TextAttr *) NULL;
  423. newscreen->DefaultTitle= (UBYTE *) NULL;
  424. newscreen->CustomBitMap= voglfront;
  425.  
  426. voglscreen             = OpenScreen(newscreen);
  427. FreeMem(newscreen,sizeof(struct NewScreen));
  428. if(!voglscreen) {
  429.     AMIGA_exit();
  430.     printf("***warning*** unable to open a Screen\n");
  431.     goto initproblem;
  432.     }
  433.  
  434. /* allocate and initialize a window */
  435. newwindow= AllocMem((LONG) sizeof(struct NewWindow),MEMTYPE);
  436. if(!newwindow) {
  437.     AMIGA_exit();
  438.     printf("***warning*** unable to allocate a NewWindow\n");
  439.     goto initproblem;
  440.     }
  441.  
  442. /* get user-specified initial window position and size
  443.  *  The user specifies these parameters with
  444.  *
  445.  *  prefposition(long x,long y)
  446.  *  prefsize(long xs,long ys)
  447.  *
  448.  * *prior* to calling winopen() or ginit().
  449.  * Vogl initializes gx, gy, gxs, gys to -1
  450.  */
  451. getprefposandsize(&gx,&gy,&gxs,&gys);
  452. if(gx  < 0 || scrwidth  < gx)  gx = 0;
  453. if(gy  < 0 || scrheight < gy)  gy = 0;
  454. if(gxs < 0 || scrwidth  < gxs) gxs= scrwidth;
  455. if(gys < 0 || scrheight < gys) gys= scrheight;
  456.  
  457. /* the amiga driver's standard window */
  458. newwindow->LeftEdge   = (SHORT) gx;
  459. newwindow->TopEdge    = (SHORT) gy;
  460. newwindow->Width      = (SHORT) gxs;
  461. newwindow->Height     = (SHORT) gys;
  462. newwindow->DetailPen  = (UBYTE) -1;
  463. newwindow->BlockPen   = (UBYTE) -1;
  464. newwindow->IDCMPFlags = (ULONG) IDCMP_MOUSEBUTTONS | IDCMP_RAWKEY;
  465. newwindow->Flags      = REPORTMOUSE | ACTIVATE | RMBTRAP;
  466. newwindow->FirstGadget= (struct Gadget *) NULL;
  467. newwindow->CheckMark  = (struct Image *) NULL;
  468. newwindow->Title      = (UBYTE *) NULL;
  469. newwindow->Screen     = voglscreen;
  470. newwindow->BitMap     = voglfront;
  471. newwindow->MinWidth   =  0;
  472. newwindow->MinHeight  =  0;
  473. newwindow->MaxHeight  = ~0;
  474. newwindow->MaxWidth   = ~0;
  475. newwindow->Type       = CUSTOMSCREEN;
  476.  
  477. /* configuration modifications */
  478. if(!useborder) newwindow->Flags|= BORDERLESS;
  479. else {
  480.     int Yfont;
  481.     if(vdevice.wintitle && vdevice.wintitle[0]) {
  482.         newwindow->Title= (UBYTE *) vdevice.wintitle;
  483.         }
  484.     Yfont             = voglscreen->Font? voglscreen->Font->ta_YSize : 0;
  485.     voglscrbordtop    = voglscreen->WBorTop + Yfont + 1;
  486.     voglscrbordbttm   = voglscreen->WBorBottom;
  487.     voglscrbordleft   = voglscreen->WBorLeft;
  488.     voglscrbordright  = voglscreen->WBorRight;
  489.     }
  490.  
  491. /* open the window */
  492. voglwindow= OpenWindow(newwindow);
  493. FreeMem(newwindow,sizeof(struct NewWindow));
  494. if(!voglwindow) {
  495.     AMIGA_exit();
  496.     printf("***warning*** unable to allocate a NewWindow\n");
  497.     goto initproblem;
  498.     }
  499.  
  500. /* set voglrastport up */
  501. voglrastport               = &voglscreen->RastPort;
  502. voglscreen->RastPort.BitMap= voglscreen->ViewPort.RasInfo->BitMap=
  503.   (scrbufmode == DBLBUFMODE)? voglback : voglfront;
  504.  
  505. /* initialize areaBuffer (5 bytes, not words, per vertex) */
  506. voglareaBuffer= (WORD *) AllocMem((LONG) 5*MAXVRTX,MEMTYPE);
  507. if(!voglareaBuffer) {
  508.     AMIGA_exit();
  509.     printf("***warning*** unable to initialize areaBuffer for %d vertices\n",MAXVRTX);
  510.     goto initproblem;
  511.     }
  512.  
  513. voglrastport->AreaInfo= (struct AreaInfo *)
  514.   AllocMem((LONG) sizeof(struct AreaInfo),MEMTYPE);
  515. if(!voglrastport->AreaInfo) {
  516.     AMIGA_exit();
  517.     printf("***warning*** unable to initialize areaInfo\n");
  518.     goto initproblem;
  519.     }
  520. InitArea(voglrastport->AreaInfo,voglareaBuffer,MAXVRTX);
  521.  
  522. /* initialize a TmpRas */
  523. vogltmpras= (struct TmpRas *)
  524.   AllocMem((LONG) sizeof(struct TmpRas),MEMTYPE);
  525. if(!vogltmpras) {
  526.     AMIGA_exit();
  527.     printf("***warning*** unable to allocate a TmpRas\n");
  528.     goto initproblem;
  529.     }
  530.  
  531. voglplaneptr= (PLANEPTR) AllocRaster(scrwidth,scrheight);
  532. if(voglplaneptr) {
  533.     voglrastport->TmpRas= (struct TmpRas *)
  534.       InitTmpRas(vogltmpras,voglplaneptr,RASSIZE(scrwidth,scrheight));
  535.     }
  536. else {
  537.     AMIGA_exit();
  538.     printf("***warning*** unable to allocate a %dx%d raster for TmpRas\n",
  539.       scrwidth,scrheight);
  540.     goto initproblem;
  541.     }
  542.  
  543.  
  544. /* don't outline area fills with the OPen (outline color pen) */
  545. BNDRYOFF(voglrastport);
  546.  
  547. /* set up strings and fonts */
  548. voglitext   = (struct IntuiText *) AllocMem((LONG) sizeof(struct IntuiText),MEMTYPE);
  549. voglstring  = (UBYTE *)            AllocMem((LONG) MAXSTRING*sizeof(UBYTE),MEMTYPE);
  550. vogltextattr= (struct TextAttr *)  AllocMem((LONG) sizeof(struct TextAttr),MEMTYPE);
  551.  
  552. /* optionally set up double buffering via AMIGA_backbuffer() */
  553. if(scrbufmode == DBLBUFMODE) AMIGA_backbuffer();
  554.  
  555. /* initial rawkey buffer allocation */
  556. if(!rawkeybuf) {
  557.     qtyrawkeybuf= RAWKEYBUF;
  558.     rawkeybuf   = (char *) AllocMem(qtyrawkeybuf,MEMTYPE);
  559.  
  560.     if(!rawkeybuf) {    /* terminate on no buffer */
  561.         AMIGA_exit();
  562.         printf("***warning*** unable to allocate a %ld byte buffer for rawkeys\n",
  563.           qtyrawkeybuf);
  564.         goto initproblem;
  565.         }
  566.     }
  567.  
  568. /* allocate an InputEvent */
  569. voglievent= (struct InputEvent *) AllocMem(sizeof(struct InputEvent),MEMTYPE);
  570. if(!voglievent) {
  571.     AMIGA_exit();
  572.     printf("***warning*** unable to allocate an InputEvent\n");
  573.     goto initproblem;
  574.     }
  575.  
  576. /* initialize vogl screensize variables*/
  577. vdevice.sizeSx= scrwidth  - 1;        /* x: upper right corner    */
  578. vdevice.sizeSy= scrheight - 1;        /* y: upper right corner    */
  579. vdevice.depth = scrdepth;            /* z: qty bitplanes            */
  580. vdevice.sizeX = vdevice.sizeY= (scrheight < scrwidth)? scrheight : scrwidth;
  581.  
  582. /* initialize the colormap */
  583. AMIGA_mapcolor(0, 0, 0, 0);            /* black                    */
  584. AMIGA_mapcolor(1,15, 0, 0);            /* red                        */
  585. if(scrdepth >= 2) {
  586.     AMIGA_mapcolor(2, 0,15, 0);        /* green                    */
  587.     AMIGA_mapcolor(3,15,15, 0);        /* yellow                    */
  588.     if(scrdepth >= 3) {
  589.         int icolor;
  590.         AMIGA_mapcolor(4, 0, 0,15);    /* blue                        */
  591.         AMIGA_mapcolor(5,15, 0,15);    /* magenta                    */
  592.         AMIGA_mapcolor(6, 0,15,15);    /* cyan                        */
  593.         AMIGA_mapcolor(7,15,15,15);    /* white                    */
  594.  
  595.         /* make the rest, if any, black */
  596.         for(icolor= 8; icolor < (1<<scrdepth); ++icolor)
  597.           AMIGA_mapcolor(icolor,0,0,0);
  598.         }
  599.     }
  600.  
  601. return 1;
  602.  
  603. initproblem:
  604. return 0;
  605. }
  606.  
  607. /* -------------------------------------------------------------------------- */
  608.  
  609. /* makeBitMap: this function sets up one bitmap.  Double buffering, of
  610.  * course, requires two bitmaps.
  611.  */
  612. static struct BitMap *makeBitMap(void)
  613. {
  614. int            idepth;
  615. struct BitMap *bitmap=NULL;
  616.  
  617. /* allocate BitMap itself */
  618. bitmap= AllocMem((LONG) sizeof(struct BitMap),MEMTYPE);
  619.  
  620. if(bitmap) {
  621.     InitBitMap(bitmap,(LONG) scrdepth,(LONG) scrwidth,(LONG) scrheight);
  622.  
  623.     for(idepth= 0; idepth < scrdepth; ++idepth) {
  624.         bitmap->Planes[idepth]= (PLANEPTR) AllocRaster(scrwidth,scrheight);
  625.         if(!bitmap->Planes[idepth]) {    /* unable to get enough memory */
  626.             for(--idepth; idepth >= 0; --idepth)
  627.               FreeRaster(bitmap->Planes[idepth],scrwidth,scrheight);
  628.             FreeMem(bitmap,(LONG) sizeof(struct BitMap));
  629.             break;
  630.             }
  631.         BltClear(bitmap->Planes[idepth],(scrwidth>>3)*scrheight,1);
  632.         }
  633.     }
  634.  
  635. return bitmap;
  636. }
  637.  
  638. /* -------------------------------------------------------------------------- */
  639.  
  640. /* freeBitMap: this function frees up memory used by a BitMap */
  641. void freeBitMap(struct BitMap *bitmap)
  642. {
  643. int idepth;
  644.  
  645. for(idepth= scrdepth-1; idepth >= 0; --idepth) {
  646.     FreeRaster(bitmap->Planes[idepth],scrwidth,scrheight);
  647.     }
  648. FreeMem(bitmap,(LONG) sizeof(struct BitMap));
  649. }
  650.  
  651. /* -------------------------------------------------------------------------- */
  652.  
  653. /* AMIGA_exit: cleans up before returning the window to normal
  654.  *  Note: I've designed this driver so that it can be re-opened.
  655.  */
  656. int AMIGA_exit(void)
  657. {
  658. FontList *prvfontlist;
  659.  
  660. /* clear back screen */
  661. if(voglscreen) SetRast(&(voglscreen->RastPort),(unsigned long) 0);
  662.  
  663. /* close open Fonts and clean up memory use */
  664. while(fontlisthd) {
  665.     CloseFont(fontlisthd->textfont);
  666.     free((char *) fontlisthd->fontspec);
  667.     fontlisthd->textfont= NULL;
  668.     fontlisthd->fontspec= NULL;
  669.     prvfontlist         = fontlisthd;
  670.     fontlisthd          = fontlisthd->nxt;
  671.     free((char *) prvfontlist);
  672.     }
  673. fontlisthd= NULL;
  674.  
  675. /* free up rawkey buffer */
  676. if(voglievent) FreeMem(voglievent,sizeof(struct InputEvent));
  677. if(rawkeybuf)  FreeMem(rawkeybuf,qtyrawkeybuf);
  678.  
  679. if(vogltextattr->ta_Name) {
  680.     int slen;
  681.     slen= strlen((char *) vogltextattr->ta_Name);
  682.     if(slen & 1) ++slen;
  683.     FreeMem(vogltextattr->ta_Name,slen*sizeof(char));
  684.     vogltextattr->ta_Name= NULL;
  685.     }
  686. if(vogltextattr) FreeMem(vogltextattr,sizeof(struct TextAttr));
  687. if(voglstring)   FreeMem(voglstring,MAXSTRING*sizeof(UBYTE));
  688. if(voglitext)    FreeMem(voglitext,sizeof(struct IntuiText));
  689. vogltextattr= NULL;
  690. voglstring  = NULL;
  691. voglitext   = NULL;
  692.  
  693. if(voglplaneptr) {
  694.     FreeRaster(voglplaneptr,scrwidth,scrheight);
  695.     voglplaneptr= NULL;
  696.     }
  697.  
  698. if(vogltmpras) {
  699.     FreeMem(vogltmpras,sizeof(struct TmpRas));
  700.     }
  701. voglrastport->TmpRas= vogltmpras= NULL;
  702.  
  703. if(voglrastport->AreaInfo) {
  704.     FreeMem(voglrastport->AreaInfo,sizeof(struct AreaInfo));
  705.     }
  706. voglrastport->AreaInfo= NULL;
  707.  
  708. if(voglareaBuffer) {
  709.     FreeMem(voglareaBuffer,5*MAXVRTX);
  710.     }
  711. voglareaBuffer= NULL;
  712.  
  713. if(voglwindow) {
  714.     CloseWindow(voglwindow);
  715.     }
  716. voglwindow= NULL;
  717.  
  718. if(voglscreen) {
  719.     CloseScreen(voglscreen);
  720.     }
  721. voglscreen= NULL;
  722.  
  723. /* free up BitMaps */
  724. if(voglback)  freeBitMap(voglback);
  725. if(voglfront) freeBitMap(voglfront);
  726. voglfront= voglback= NULL;
  727.  
  728. /* close down Libraries */
  729. if(ConsoleDevice) {
  730.     CloseDevice((struct IORequest *) vogl_cd_ioreq);
  731.     }
  732. ConsoleDevice= NULL;
  733. if(DiskfontBase) {
  734.     CloseLibrary((struct Library *) DiskfontBase);
  735.     }
  736. DiskfontBase= NULL;
  737. if(GfxBase) {
  738.     CloseLibrary((struct Library *) GfxBase);
  739.     }
  740. GfxBase= NULL;
  741. if(IntuitionBase) {
  742.     CloseLibrary((struct Library *) IntuitionBase);
  743.     }
  744. IntuitionBase= NULL;
  745.  
  746. /* free up memory for Console Device */
  747. if(vogl_cd_ioreq) {
  748.     FreeMem(vogl_cd_ioreq,sizeof(struct IOStdReq));
  749.     }
  750. vogl_cd_ioreq= NULL;
  751.  
  752. return 0;
  753. }
  754.  
  755. /* -------------------------------------------------------------------------- */
  756.  
  757. /* AMIGA_draw: draws a line from the current graphics position to (x, y) */
  758. void AMIGA_draw(
  759.   int x,
  760.   int y)
  761. {
  762. Move(voglrastport,vdevice.cpVx,vdevice.sizeSy - vdevice.cpVy);
  763. Draw(voglrastport,x,vdevice.sizeSy - y);
  764. }
  765.  
  766. /* -------------------------------------------------------------------------- */
  767.  
  768. /* AMIGA_getkey: grab a character from the keyboard
  769.  *  (empties voglkeybuf)
  770.  */
  771. int AMIGA_getkey(void)
  772. {
  773. int   key;
  774. int   mb,wx,wy;        /* to make AMIGA_locator happy */
  775. int   newikeybgn;
  776. ULONG signals;
  777.  
  778. newikeybgn= ikeybgn + 1;
  779. if(newikeybgn >= KEYBUF) newikeybgn= 0;
  780.  
  781. if(newikeybgn != ikeyend) {
  782.     /* update ikeybgn index and get key from voglkeybuf */
  783.     ikeybgn= newikeybgn;
  784.     key    = voglkeybuf[ikeybgn];
  785.     }
  786.  
  787. else {
  788.  
  789.     /* block until a key is hit */
  790.     do {
  791.         signals= Wait(1L << voglwindow->UserPort->mp_SigBit);
  792.         if(signals & (1L << voglwindow->UserPort->mp_SigBit)) {
  793.             mb= AMIGA_locator(&wx,&wy);
  794.             }
  795.         } while(newikeybgn == ikeyend);
  796.  
  797.     /* update ikeybgn index and get key from voglkeybuf */
  798.     ikeybgn= newikeybgn;
  799.     key    = voglkeybuf[ikeybgn];
  800.     }
  801.  
  802. return key;
  803. }
  804.  
  805. /* -------------------------------------------------------------------------- */
  806.  
  807. /* AMIGA_checkkey: Check if a keyboard key has been hit. If so return it
  808.  *  Otherwise, return 0.  Note: this function does actually read the
  809.  *  key (ie. remove it from the buffer) if one has been hit.  That's
  810.  *  the way the qread/qtest functions like it.
  811.  */
  812. int AMIGA_checkkey(void)
  813. {
  814. int key;
  815. int mb,wx,wy;        /* to make AMIGA_locator happy */
  816. int newikeybgn;
  817.  
  818.  
  819. /* fill up rawkeybuf with any pending key hits */
  820. mb = AMIGA_locator(&wx,&wy);
  821.  
  822. newikeybgn= ikeybgn + 1;
  823. if(newikeybgn >= KEYBUF) newikeybgn= 0;
  824. if(newikeybgn != ikeyend) {
  825.     ikeybgn= newikeybgn;
  826.     key    = voglkeybuf[ikeybgn];
  827.     }
  828. else key= 0;
  829.  
  830. return key;
  831. }
  832.  
  833. /* -------------------------------------------------------------------------- */
  834.  
  835. /* AMIGA_handlekey: this function handles RAWKEYs  (fills up voglkeybuf)
  836.  *     voglkeybuf                                      voglkeybuf
  837.  *   |uuuddddddduuuuu|    u=unused  d=data            |ddddduuuuuuudd|
  838.  *      ^       ^                                           ^     ^
  839.  *   ikeybgn    ikeyend   (always point to unused)     ikeyend    ikeybgn
  840.  */
  841. static void AMIGA_handlekey(struct IntuiMessage *Imsg)
  842. {
  843. int      dbl=0;
  844. LONG     numchars;
  845. unsigned newikeyend;
  846.  
  847. /* convert rawkey message into a vanilla key */
  848. do {
  849.     voglievent->ie_Class           = IECLASS_RAWKEY;
  850.     voglievent->ie_Code            = Imsg->Code;
  851.     voglievent->ie_Qualifier       = Imsg->Qualifier;
  852.     voglievent->ie_position.ie_addr= *((APTR*) Imsg->IAddress);
  853.  
  854.     numchars= RawKeyConvert(voglievent,(STRPTR) rawkeybuf,qtyrawkeybuf-1,NULL);
  855.     dbl    = numchars == -1 && !rawkeybuf[0];
  856.  
  857.     if(dbl) {    /* double size of rawkeybuf to enable conversion */
  858.         FreeMem(rawkeybuf,qtyrawkeybuf);
  859.         qtyrawkeybuf<<= 1;
  860.         rawkeybuf     = AllocMem(qtyrawkeybuf,MEMTYPE);
  861.         if(!rawkeybuf) {    /* unable to double rawkey buffer! */
  862.             qtyrawkeybuf= 0;
  863.             AMIGA_exit();
  864.             }
  865.         }
  866.     } while(dbl);
  867.  
  868. /* numchars contains the number of characters placed within the rawkeybuf.
  869.  * Key up events and key sequences which do not generate any data for the
  870.  * program (deadkeys, already intercepted sequences, etc) will return zero.
  871.  *
  872.  * Special keys (HELP, cursor keys, FKeys, etc) return multiple characters
  873.  * that have to be parsed below.
  874.  *
  875.  * There are a number of qualifiers available, most of which are currently
  876.  * being ignored by this vogl-amiga driver.  However, for reference purposes:
  877.  *
  878.  * (Imsg->Code & 0x80)? key-up : key-down
  879.  * 
  880.  *  Imsg->Qualifier can be "anded" with
  881.  * 
  882.  *    IEQUALIFIER_CAPSLOCK       IEQUALIFIER_LSHIFT         IEQUALIFIER_RBUTTON       
  883.  *    IEQUALIFIER_CONTROL        IEQUALIFIER_MIDBUTTON      IEQUALIFIER_RCOMMAND      
  884.  *    IEQUALIFIER_INTERRUPT      IEQUALIFIER_MULTIBROADCAST IEQUALIFIER_RELATIVEMOUSE 
  885.  *    IEQUALIFIER_LALT           IEQUALIFIER_NUMERICPAD     IEQUALIFIER_REPEAT        
  886.  *    IEQUALIFIER_LCOMMAND       IEQUALIFIER_RALT           IEQUALIFIER_RSHIFT        
  887.  *    IEQUALIFIER_LEFTBUTTON     
  888.  */
  889.  
  890. /* key is pressed down */
  891. if(!(Imsg->Code & 0x80)) {
  892.  
  893.     /* handlekey only accepts alphameric (assumed to be caps), numeric, and unshifted
  894.      * punctuation.  Report sequences (function keys, help, cursor keys, etc) are
  895.      * ignored!
  896.      */
  897.     newikeyend= ikeyend + 1;
  898.     if(newikeyend >= KEYBUF) newikeyend= 0;
  899.     
  900.     if(newikeyend != ikeybgn && rawkeybuf[0] != 0x9b) {    /* 0x9b is a report sequence */
  901.         if     (islower(rawkeybuf[0]))   rawkeybuf[0]= toupper(rawkeybuf[0]);    /* lower -> upper    */
  902.         else if(rawkeybuf[0] == '\177')  rawkeybuf[0]= '\020';                    /* DEL key mapping    */
  903.         voglkeybuf[ikeyend]= rawkeybuf[0];
  904.         ikeyend            = newikeyend;
  905.         }
  906.     }
  907. }
  908.  
  909. /* --------------------------------------------------------------------- */
  910.  
  911. /* AMIGA_locator:
  912.  *    return the window location of the cursor,
  913.  *  plus which mouse button, if any, has been pressed.
  914.  *
  915.  * Bit   0     1      2    is 1 when button is pressed down
  916.  *     |left|middle|right| is 0 when button is released
  917.  */
  918. int AMIGA_locator(
  919.   int *wx,
  920.   int *wy)
  921. {
  922. int                  mb  = 0;
  923. struct Message      *Mmsg= NULL;
  924. struct IntuiMessage *Imsg= NULL;
  925.  
  926. /* get current mouse position */
  927. *wx= voglwindow->MouseX;
  928. *wy= vdevice.sizeSy - voglwindow->MouseY;
  929.  
  930. while(Mmsg= GetMsg(voglwindow->UserPort)) {
  931.     Imsg= (struct IntuiMessage *) Mmsg;
  932.  
  933.     switch(Imsg->Class) {
  934.  
  935.     case IDCMP_MOUSEBUTTONS:
  936.  
  937.         switch(Imsg->Code) {
  938.  
  939.         case SELECTDOWN:    /* left   mouse pressed        */
  940.             mb|= 01;
  941.             break;
  942.  
  943.         case SELECTUP:        /* left   mouse released    */
  944.             mb&= ~01;
  945.             break;
  946.  
  947.         case MIDDLEDOWN:    /* middle mouse pressed        */
  948.             mb|= 02;
  949.             break;
  950.  
  951.         case MIDDLEUP:        /* middle mouse released    */
  952.             mb&= ~02;
  953.             break;
  954.  
  955.         case MENUDOWN:        /* right  mouse pressed        */
  956.             mb|= 04;
  957.             break;
  958.  
  959.         case MENUUP:        /* right  mouse released    */
  960.             mb&= ~04;
  961.             break;
  962.  
  963.         default:
  964.             break;
  965.             }
  966.         break;
  967.  
  968.     case IDCMP_RAWKEY:        /* a key was hit/released    */
  969.         AMIGA_handlekey(Imsg);
  970.         break;
  971.  
  972.     default:                /* unsupported Intuimessage    */
  973.         break;
  974.         }
  975.  
  976.     ReplyMsg(Mmsg);
  977.     }
  978.  
  979. return mb;
  980. }
  981.  
  982. /* -------------------------------------------------------------------------- */
  983.  
  984. /* AMIGA_clear: Clear the screen to current color */
  985. void AMIGA_clear(void)
  986. {
  987. SetRast(voglrastport,(unsigned long) currcolor);
  988. }
  989.  
  990. /* -------------------------------------------------------------------------- */
  991.  
  992. /* AMIGA_color: set the current drawing color index */
  993. void AMIGA_color(int icolor)
  994. {
  995. currcolor= icolor;                /* used by string/char rendering */
  996. SetAPen(voglrastport,icolor);
  997. }
  998.  
  999. /* -------------------------------------------------------------------------- */
  1000.  
  1001. /* AMIGA_mapcolor: change index icolor in the color map to the appropriate
  1002.  *  r, g, b, value.
  1003.  */
  1004. void AMIGA_mapcolor(
  1005.   int icolor,
  1006.   int r,
  1007.   int g,
  1008.   int b)
  1009. {
  1010. if(icolor >= (1<<scrdepth)) {
  1011.     return;
  1012.     }
  1013.  
  1014. SetRGB4(&voglscreen->ViewPort,
  1015.   (long)          icolor,
  1016.   (unsigned long) r,
  1017.   (unsigned long) g,
  1018.   (unsigned long) b);
  1019. }
  1020.  
  1021. /* -------------------------------------------------------------------------- */
  1022.  
  1023. /* AMIGA_font: Set up a hardware font. Return 1 on success 0 otherwise
  1024.  *  I have come up with a little convention for the fontspec:
  1025.  *    fontname;height[;{BEIPU}]
  1026.  *   B == bold
  1027.  *   E == extended
  1028.  *   I == italic
  1029.  *   P == plain (default)
  1030.  *   U == underlined
  1031.  *
  1032.  *  Returns: 0=failure-to-open
  1033.  *           1=successful font open
  1034.  */
  1035. int AMIGA_font(char *fontspec)
  1036. {
  1037. char             type='P';        /* font spec type            */
  1038. char            *fsh;            /* ptr to font spec height    */
  1039. char            *fst;            /* ptr to font spec type    */
  1040. int              h;                /* height                    */
  1041. int              slen;            /* length of fontname        */
  1042. FontList        *fontlist    = NULL;
  1043. struct TextFont *vogltextfont= NULL;
  1044. static FontList *oldfontlist = NULL;
  1045.  
  1046. /* check over FontList for fontspec */
  1047. for(fontlist= fontlisthd; fontlist; fontlist= fontlist->nxt) {
  1048.  
  1049.     if(!strcmp(fontlist->fontspec,fontspec)) {
  1050.     
  1051.         if(fontlist == oldfontlist) {    /* font unchanged! */
  1052.             return;
  1053.             }
  1054.  
  1055.         vdevice.hheight= fontlist->textfont->tf_YSize;
  1056.         vdevice.hwidth = fontlist->textfont->tf_XSize;
  1057.     
  1058.         /* set the font */
  1059.         SetFont(voglrastport,fontlist->textfont);
  1060.         oldfontlist= fontlist;
  1061.         return 1;
  1062.         }
  1063.     }
  1064.  
  1065. /* get font-separator pointers */
  1066. fsh                   = strchr(fontspec,FONTSEP);    /* nominal font height        */
  1067. fst                   = strchr(fsh+1,FONTSEP);        /* type of font                */
  1068. vogltextattr->ta_Style= (UBYTE) 0;                    /* default style == plain    */
  1069. vogltextattr->ta_Flags= (UBYTE) 0;                    /* default style == plain    */
  1070.  
  1071. if(fsh) {
  1072.     sscanf(fsh+1,"%hu",&vogltextattr->ta_YSize);
  1073.     *fsh= '\0';
  1074.  
  1075.     if(fst) {
  1076.         for(++fst; *fst; ++fst) switch(*fst) {
  1077.  
  1078.         case 'B':    /* bold */
  1079.         case 'b':
  1080.             vogltextattr->ta_Style|= FSF_BOLD;
  1081.             break;
  1082.  
  1083.         case 'E':    /* extended (extra wide) */
  1084.         case 'e':
  1085.             vogltextattr->ta_Style|= FSF_EXTENDED;
  1086.             break;
  1087.  
  1088.         case 'I':    /* italic */
  1089.         case 'i':
  1090.             vogltextattr->ta_Style|= FSF_ITALIC;
  1091.             break;
  1092.  
  1093.         case 'P':    /* plain */
  1094.         case 'p':
  1095.             break;
  1096.  
  1097.         case 'U':    /* underlined */
  1098.         case 'u':
  1099.             vogltextattr->ta_Style|= FSF_UNDERLINED;
  1100.             break;
  1101.  
  1102.         default:    /* ignored */
  1103.             break;
  1104.             }
  1105.         }
  1106.     }
  1107. else vogltextattr->ta_YSize= 11L;            /* default height == 11 pts    */
  1108.  
  1109. /* free up old ta_Name */
  1110. if(vogltextattr->ta_Name) {
  1111.     slen= strlen((char *) vogltextattr->ta_Name);
  1112.     if(slen & 1) ++slen;
  1113.     FreeMem(vogltextattr->ta_Name,slen*sizeof(char));
  1114.     vogltextattr->ta_Name= NULL;
  1115.     }
  1116. slen= strlen(fontspec) + 6;
  1117. if(slen & 1) ++slen;
  1118. vogltextattr->ta_Name= (STRPTR) AllocMem((LONG) slen*sizeof(char),MEMTYPE);
  1119. sprintf((char *) vogltextattr->ta_Name,"%s.font",fontspec);
  1120.  
  1121. if(fsh) *fsh= FONTSEP;                            /* restore *fsh            */
  1122.  
  1123.  
  1124. /* attempt to open requested font */
  1125. vogltextfont= OpenDiskFont(vogltextattr);        /* open the font        */
  1126. if(vogltextfont) {
  1127.     SetFont(voglrastport,vogltextfont);            /* set the font            */
  1128.  
  1129.     /* set up FontList */
  1130.     head_link(FontList,fontlisthd,"FontList");
  1131.     stralloc(fontlisthd->fontspec,fontspec,"fontspec");
  1132.     fontlisthd->textfont= vogltextfont;
  1133.     oldfontlist         = fontlisthd;
  1134.     vdevice.hheight     = fontlisthd->textfont->tf_YSize;
  1135.     vdevice.hwidth      = fontlisthd->textfont->tf_XSize;
  1136.     }
  1137. else {    /* failure to open requested font */
  1138.     vdevice.hheight= 0;
  1139.     vdevice.hwidth = 0;
  1140.     return 0;
  1141.     }
  1142.  
  1143. return 1;
  1144. }
  1145.  
  1146. /* -------------------------------------------------------------------------- */
  1147.  
  1148. /* AMIGA_char: outputs one char */
  1149. void AMIGA_char(char c)
  1150. {
  1151. char s[2];
  1152.  
  1153. s[0]= c;
  1154. s[1]= '\0';
  1155. AMIGA_string(s);
  1156. }
  1157.  
  1158. /* -------------------------------------------------------------------------- */
  1159.  
  1160. /* AMIGA_string: Display a string at the current drawing position */
  1161. void AMIGA_string(char *s)
  1162. {
  1163. /* set up the IntuiText */
  1164. voglitext->FrontPen = (UBYTE) currcolor;    /* set text's foreground color        */
  1165. voglitext->BackPen  = (UBYTE) 0;            /* background color ignored            */
  1166. voglitext->DrawMode = JAM1;                    /* just use fgd color                */
  1167.  
  1168. voglitext->LeftEdge = vdevice.cpVx;            /* set x position                    */
  1169. /* set y position            */
  1170. voglitext->TopEdge  = vdevice.sizeSy - vdevice.cpVy - vdevice.hheight;
  1171.  
  1172. voglitext->ITextFont= NULL;                    /* use default font                    */
  1173. strcpy((char *) voglstring,s);                /* copy user's string to voglstring    */
  1174. voglitext->IText    = voglstring;            /* print out voglstring                */
  1175. voglitext->NextText = NULL;                    /* no next text                        */
  1176.  
  1177. PrintIText(voglrastport,voglitext,0L,0L);    /* use printIText to render            */
  1178. }
  1179.  
  1180. /* -------------------------------------------------------------------------- */
  1181.  
  1182. /* AMIGA_fill: fill a polygon */
  1183. void AMIGA_fill(
  1184.   int  n,
  1185.   int *x,
  1186.   int *y)
  1187. {
  1188. int ifill;
  1189. int result;
  1190.  
  1191. if(AreaMove(voglrastport,(long) x[0],(long) vdevice.sizeSy - y[0]) < 0) {
  1192.     printf("***warning*** unable to fill polygon with %d vertices\n",n);
  1193.     return;
  1194.     }
  1195.  
  1196. for(ifill= 1; ifill < n; ++ifill) {
  1197.     if(AreaDraw(voglrastport,(long) x[ifill],(long) vdevice.sizeSy - y[ifill]) < 0) {
  1198.         printf("***warning*** unable to fill polygon with %d vertices\n",n);
  1199.         return;
  1200.         }
  1201.     }
  1202.  
  1203. AreaEnd(voglrastport);
  1204.  
  1205. vdevice.cpVx = x[n - 1];
  1206. vdevice.cpVy = y[n - 1];
  1207. }
  1208.  
  1209. /* -------------------------------------------------------------------------- */
  1210.  
  1211. /* AMIGA_backbuffer: draw in back buffer, display front
  1212.  *  Returns 0=success
  1213.  *         -1=failure
  1214.  */
  1215. int AMIGA_backbuffer(void)
  1216. {
  1217. if(scrbufmode == SNGLBUFMODE) {    /* begin double buffer mode */
  1218.     scrbufmode                 = DBLBUFMODE;
  1219.     voglscreen->RastPort.BitMap= voglscreen->ViewPort.RasInfo->BitMap= voglback;
  1220.     voglscreen->RastPort.Flags = DBUFFER;
  1221.     }
  1222.  
  1223. if(voglback && voglscreen->RastPort.BitMap != voglback) {
  1224.     MakeScreen(voglscreen);    /* make screen's new copper list            */
  1225.     RethinkDisplay();        /* combine copper lists into single View    */
  1226.     voglscreen->RastPort.BitMap= voglscreen->ViewPort.RasInfo->BitMap= voglback;
  1227.     voglwindow->RPort->BitMap  = voglback;
  1228.     }
  1229.  
  1230. return 0;
  1231. }
  1232.  
  1233. /* -------------------------------------------------------------------------- */
  1234.  
  1235. /* AMIGA_swapbuffer: swap the front and back buffers */
  1236. int AMIGA_swapbuffer(void)
  1237. {
  1238. struct BitMap *voglswap;
  1239.  
  1240. if(!voglback || scrbufmode != DBLBUFMODE) {
  1241.     return 0;
  1242.     }
  1243.  
  1244. /* display back buffer */
  1245. MakeScreen(voglscreen);    /* make screen's new copper list            */
  1246. RethinkDisplay();        /* combine copper lists into single View    */
  1247.  
  1248. /* swap front and back BitMap buffers */
  1249. voglswap                   = voglfront;
  1250. voglfront                  = voglback;
  1251. voglback                   = voglswap;
  1252. voglscreen->RastPort.BitMap= voglscreen->ViewPort.RasInfo->BitMap= voglback;
  1253. voglwindow->RPort->BitMap  = voglback;
  1254.  
  1255. return 0;
  1256. }
  1257.  
  1258. /* -------------------------------------------------------------------------- */
  1259.  
  1260. /* AMIGA_frontbuffer: draw in the front buffer */
  1261. void AMIGA_frontbuffer(void)
  1262. {
  1263. voglscreen->RastPort.BitMap= voglscreen->ViewPort.RasInfo->BitMap= voglfront;
  1264. voglwindow->RPort->BitMap  = voglfront;
  1265. }
  1266.  
  1267. /* --------------------------------------------------------------------------
  1268.  * _AMIGA_devcpy
  1269.  *
  1270.  *    copy the amiga device into vdevice.dev.
  1271.  */
  1272. void _AMIGA_devcpy(void)
  1273. {
  1274. vdevice.dev= amigadev;
  1275. }
  1276.  
  1277. /* ==========================================================================
  1278.  * Source Code:
  1279.  *  The test code here exercises the amiga driver by itself and is not
  1280.  *  expected to be the "usual" way of using it.  The usual way is via
  1281.  *  standard vogl methods.
  1282.  */
  1283.  
  1284. /* --------------------------------------------------------------------- */
  1285.  
  1286. /* DT_title: this function sets up the window's title */
  1287. void DT_title(char *buf)
  1288. {
  1289. static char titlebuf[RAWKEYBUF];
  1290.  
  1291. strcpy(titlebuf,buf);
  1292. vdevice.wintitle= titlebuf;
  1293. }
  1294.  
  1295. /* --------------------------------------------------------------------- */
  1296.  
  1297. #ifdef SASC
  1298. void __regargs __checkabort (void)
  1299. {
  1300. /* empty */
  1301. }
  1302. #endif
  1303.  
  1304. /* --------------------------------------------------------------------- */
  1305.